//package com.ikas.ai.server.module.steady.delaytask;
//
//import cn.hutool.core.date.DateTime;
//import com.ikas.ai.server.module.alarm.enums.SolvedEnum;
//import com.ikas.ai.server.module.steady.enums.AlarmConditionEnum;
//import com.ikas.ai.server.module.steady.enums.DelayStatusEnum;
//import com.ikas.ai.server.module.steady.model.po.SteadyAlarmData;
//import com.ikas.ai.server.module.steady.service.SteadyAlarmDataService;
//import com.ikas.ai.server.module.steady.service.SteadyMonitorMeteService;
//import com.ikas.ai.utils.DateTimeUtil;
//import com.ikas.ai.utils.RedisUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.InitializingBean;
//import org.springframework.data.redis.core.ZSetOperations;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//import java.util.Objects;
//import java.util.Set;
//
///**
// * @author: wang.qining
// * @date: 2024/3/7 15:02
// */
//@Slf4j
//@Component
//public class SteadyDelayService implements InitializingBean {
//    public static final String ORDER_DELAY_TASK_KEY = "steady:delaytask";
//    @Resource
//    private RedisUtil redisUtil;
//    @Resource
//    private SteadyMonitorMeteService steadyMonitorMeteService;
//    @Resource
//    private SteadyAlarmDataService steadyAlarmDataService;
//
//    /**
//     * 生成延时队列
//     *
//     * @param meteId 测点id
//     * @param steadyAlarmId 稳态预警id
//     * @param duration   延时时长
//     */
//    public void produce(Long meteId, Long steadyAlarmId, Long alarmTime, Integer duration) {
//        log.info("添加阈值预警记录：" + "测点ID：" + meteId + ",预警记录id：" +steadyAlarmId + ",延迟预警时间:" + duration + ",当前时间" + DateTimeUtil.getDateTimeString());
//        // 放到延时队列中的数据格式是：meteId,steadyAlarmId
//        String data = meteId + "," + steadyAlarmId + "," + alarmTime;
//        long time = System.currentTimeMillis() + duration * 1000;
//        redisUtil.getZSetOperations().add(
//                ORDER_DELAY_TASK_KEY,
//                data,
//                time
//        );
//
//    }
//
//    //延时任务，也是异步任务，延时任务达到时效做延时预警逻辑处理
//    public void consuming() {
//        Long currentTime = System.currentTimeMillis();
//        Set<ZSetOperations.TypedTuple<String>> steadySet = redisUtil.getZSetOperations().rangeByScoreWithScores(
//                ORDER_DELAY_TASK_KEY,
//                //延时任务score最小值
//                0,
//                //延时任务score最大值（当前时间）
//                currentTime
//        );
//        if (steadySet != null && steadySet.size() > 0) {
//            for (ZSetOperations.TypedTuple<String> steady : steadySet) {
//                try {
//                    String data = steady.getValue();
//                    String[] split = data.split(",");
//                    Long meteId = Long.valueOf(split[0]);
//                    Long steadyAlarmId = Long.valueOf(split[1]);
//                    SteadyAlarmData alarmData = steadyAlarmDataService.getById(steadyAlarmId);
//                    // 查询此时该测点是否已经产生了预警，如果有，则不再产生
//                    // 存在一种情况：工况结束时，会将该工况中产生的预警记录删除，所以alarmData可能为空
//                    if (alarmData == null || (Objects.equals(alarmData.getSolved(), SolvedEnum.UN_SOLVED.getSolved()) && alarmData.getDelayStatus() == 2)) {
//                        // 直接删除延时任务
//                        redisUtil.getZSetOperations().remove(ORDER_DELAY_TASK_KEY, steady.getValue());
//                        return;
//                    }
//                    log.info("创建" + steady.getValue() + "预警记录" + "_当前时间" + DateTimeUtil.getDateTimeString());
//                    // 根据id去查询告警产生时间(即测点上报时间)-延时时间，这一整个区间的数据，根据预警条件(大于小于)确定是返回最大值还是最小值
//                    // 如果是大于，则返回最小值，逻辑是：如果该区间的最小值都大于当前值，则说明应该产生预警
//                    // 如果是小于，则返回最大值，逻辑是：如果该区间的最大值都小于当前值，则说明应该产生预警
//                    Double alarmThreshold = alarmData.getAlarmThreshold();
//                    // 此处封装tdEngine查询开始及结束时间
//                    long tdEngineSelectStartTime = Long.parseLong(split[2]);
//                    Long tdEngineSelectEndTime = tdEngineSelectStartTime + alarmData.getDelayAlarmDuration() * 1000;
//                    //预警条件
//                    AlarmConditionEnum alarmCondition = AlarmConditionEnum.getEnumByValue(alarmData.getAlarmCondition());
//                    log.info("alarmCondition:{}", alarmCondition);
//                    Double extremeValue = steadyMonitorMeteService.getExtremeValueFromTd(meteId, tdEngineSelectStartTime, tdEngineSelectEndTime, alarmCondition, 0);
//
//                    // 更新预警记录
//                    SteadyAlarmData steadyAlarmData = new SteadyAlarmData();
//                    steadyAlarmData.setId(steadyAlarmId);
//                    // 算出来绝对值
//                    if (steadyMonitorMeteService.isMeetCondition2(alarmThreshold, extremeValue, alarmCondition)) {
//                        // 预警，更新预警时间和预警状态
//                        steadyAlarmData.setAlarmTime(DateTime.of(currentTime).toTimestamp());
//                        steadyAlarmData.setDelayStatus(DelayStatusEnum.DELAY_ALARMED.getValue());
//                    } else {
//                        // 不预警
//                        steadyAlarmData.setDelayStatus(DelayStatusEnum.DELAY_NOT_ALARMED.getValue());
//                    }
//                    steadyAlarmDataService.updateById(steadyAlarmData);
//
//                    // 关闭之后，将延时任务从队列中删除
//                    redisUtil.getZSetOperations().remove(ORDER_DELAY_TASK_KEY, steady.getValue());
//                } catch (Exception e) {
//                    redisUtil.getZSetOperations().remove(ORDER_DELAY_TASK_KEY, steady.getValue());
//                    log.info("消费队列时发生错误：" + e.getMessage());
//                }
//
//            }
//        }
//    }
//
//    //该类对象Bean实例化之后，就开启while扫描任务
//    @Override
//    public void afterPropertiesSet() throws Exception {
//        new Thread(() -> {
//            while (true) {
//                try {
//                    consuming();
//                    Thread.sleep(1000);
//                } catch (Exception e) {
//                    log.error("消费延时队列失败：" + e.getMessage());
//                }
//            }
//        }).start();
//    }
//
//}
